package com.pearl.camunda.study02.controller;

import cn.hutool.core.collection.CollUtil;
import com.pearl.camunda.study02.common.R;
import com.pearl.camunda.study02.pojo.param.StartProcessInstanceParams;
import com.pearl.camunda.study02.pojo.query.ProcessDefinitionQueryParams;
import com.pearl.camunda.study02.pojo.vo.ProcessDefinitionVO;
import com.pearl.camunda.study02.pojo.vo.TaskVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.camunda.bpm.engine.ManagementService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.impl.persistence.entity.VariableInstanceEntity;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.repository.ProcessDefinitionQuery;
import org.camunda.bpm.engine.rest.dto.VariableValueDto;
import org.camunda.bpm.engine.rest.dto.runtime.ProcessInstanceDto;
import org.camunda.bpm.engine.rest.dto.runtime.ProcessInstanceWithVariablesDto;
import org.camunda.bpm.engine.rest.dto.runtime.modification.ProcessInstanceModificationInstructionDto;
import org.camunda.bpm.engine.rest.dto.task.TaskDto;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.runtime.ProcessInstanceWithVariables;
import org.camunda.bpm.engine.runtime.ProcessInstantiationBuilder;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.engine.task.TaskQuery;
import org.camunda.bpm.engine.variable.Variables;
import org.camunda.bpm.engine.variable.value.StringValue;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * @author TD
 * @version 1.0
 * @date 2023/7/31
 */
@Tag(name = "流程实例")
@RestController
@RequestMapping("/process")
public class ProcessController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Operation(summary = "查询流程定义列表")
    @GetMapping("/getProcessDefinitionList")
    public R<List<ProcessDefinitionVO>> query(@ParameterObject ProcessDefinitionQueryParams params) {
        // 1. 定义条件
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery()
                .latestVersion() // 只查询最后一个版本
                .suspended() // 1 激活 2 挂起
                .processDefinitionNameLike("%" + params.getNameLike() + "%");// 名称模糊查询
        // 2. 执行列表查询
        List<ProcessDefinition> processDefinitionList = query.list();
        // 3. 对象转换
        return R.success(ProcessDefinitionVO.fromProcessDefinition(processDefinitionList));
    }

    @Operation(summary = "启动流程")
    @PostMapping("/start")
    public R<String> start(@RequestBody StartProcessInstanceParams params) {
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(params.getProcessDefinitionId(), params.getVariables());
        return R.success(processInstance.getProcessInstanceId());
    }

    @Operation(summary = "查询所有待办任务")
    @GetMapping("/getTaskList")
    public R<List<TaskVO>> getTaskList() {
        // 1. 定义条件
        TaskQuery taskQuery = taskService.createTaskQuery();
        // 2. 执行列表查询
        List<Task> taskList = taskQuery.list();
        // 3. 对象转换
        return R.success(TaskVO.fromTask(taskList));
    }

    @Operation(summary = "完成任务")
    @PostMapping("/complete")
    public R<?> complete(String taskId) {
        taskService.complete(taskId);
        return R.success();
    }

    @Autowired
    ManagementService managementService;

    public void testQueryAPI() {
        List<Task> tasks1 = taskService.createTaskQuery() // 创建查询对象
                .taskAssignee("kermit") // 任务处理人
                .processVariableValueEquals("orderId", "0815") // 变量值 orderId=0815
                .orderByDueDate().asc() // 截止时期排除
                .list();

        List<Task> tasks2 = taskService.createTaskQuery() // 创建查询对象
                .taskAssignee("kermit") // 任务处理人
                .processVariableValueEquals("orderId", "0815") // 变量值 orderId=0815
                .orderByDueDate().asc() // 截止时期排除
                .unlimitedList();

        // 根据名称查询任务列表
        List<Task> tasks3 = taskService.createNativeTaskQuery()
                .sql("SELECT * FROM "
                        + managementService.getTableName(Task.class) // 使用ManagementService获取任务表名
                        + " T WHERE T.NAME_ = #{taskName}")
                .parameter("taskName", "aOpenTask") // 传入参数
                .list();
    }
}
